#include "ft32f0xx.h"
#include "stdio.h"
#include "string.h"
#define SECTOR_SIZE 512

#define ALIGN_WIDTH 4
// ft32f030的flash是以512byte作为一个块的
//在bootloader中，擦除将以512字节为一个块进行擦除

void flash_read(uint8_t *readBuf, uint32_t readLen, uint32_t flashAddr)
{
    memcpy(readBuf, (char *)flashAddr, readLen);
}

void flash_write(uint8_t *writeBuf, uint32_t writeLen, uint32_t flashAddr)
{
    volatile uint32_t writeTmp = 0xFFFFFFFF;
    volatile uint32_t address = 0;
    uint32_t address_end = 0;
    volatile uint32_t cpySize = 0;
    address = flashAddr;
    address_end = flashAddr + writeLen;
    FLASH_Unlock();
    FLASH_ClearFlag(FLASH_FLAG_EOP | FLASH_FLAG_PGERR | FLASH_FLAG_WRPERR);
    while (address < address_end)
    {
        writeTmp = 0xFFFFFFFF;
        cpySize = ((address + ALIGN_WIDTH) > address_end) ? (address_end - address) : ALIGN_WIDTH;
        memcpy((unsigned char *)&writeTmp, writeBuf, cpySize);
        if (FLASH_ProgramWord(address, writeTmp) != FLASH_COMPLETE)
        {
            FLASH_Lock();
            while (1)
                ; // hang write failed update failed
        }
        address += cpySize;
        writeBuf += cpySize;
    }
    FLASH_Lock();
}

void flash_erase(uint32_t startAddr, uint32_t length)
{
    int ii = 0;
    uint32_t sectors = 0;
    if (startAddr % SECTOR_SIZE != 0)
    {
        while (1)
            ; // hang not allow other address to erase
    }
    if (length % 512 != 0)
    {
        while (1)
            ; // hang not allow other length to erase
    }

    /* Clear pending flags (if any) */
    FLASH_ClearFlag(FLASH_FLAG_EOP | FLASH_FLAG_PGERR | FLASH_FLAG_WRPERR);
    FLASH_Unlock();
    sectors = length / SECTOR_SIZE;
    for (ii = 0; ii < sectors; ii++)
    {
        if (FLASH_ErasePage(startAddr + ii * SECTOR_SIZE) != FLASH_COMPLETE)
        {
            FLASH_Lock();
            while (1)
                ; // hang could not erase flash
        }
    }
    FLASH_Lock();
}
